package org.dynamo.database.reverse.config.reader.internal;
/*******************************************************************************
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Jean Neveux - initial API and implementation
 *******************************************************************************/
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.dynamo.database.reverse.emf.metadata.Catalog;
import org.dynamo.database.reverse.emf.metadata.Column;
import org.dynamo.database.reverse.emf.metadata.ForeignKey;
import org.dynamo.database.reverse.emf.metadata.Index;
import org.dynamo.database.reverse.emf.metadata.Key;
import org.dynamo.database.reverse.emf.metadata.MetadataFactory;
import org.dynamo.database.reverse.emf.metadata.Table;
import org.dynamo.database.reverse.emf.metadata.UniqueKey;

public class DatabaseCollector {

	private Catalog catalog;
	private static final MetadataFactory factory = MetadataLoader.initModel();
	
	private Map<String, Table> tables;
	private Map<String, List<ForeignKey>> oneToManyCandidates;
	
	public DatabaseCollector(String catalog, String schema)
	{
		this.catalog = factory.createCatalog();
		this.catalog.setName(catalog);
		this.catalog.setSchema(factory.createSchema());
		this.catalog.getSchema().setName(schema);
	}
	
	public void SaveModel(String path)
	{
		MetadataLoader.save(path, catalog);
	}
	
	public void loadModel(String path)
	{
		catalog = MetadataLoader.load(path);
	}
	
	public Iterator<Table> iterateTables() {
		return this.catalog.getSchema().getTables().iterator();
	}

	public void setOneToManyCandidates(Map<String, List<ForeignKey>> oneToManyCandidates) {
		this.oneToManyCandidates = oneToManyCandidates;
		Collection<List<ForeignKey>> fkValues = oneToManyCandidates.values();
		List<ForeignKey> fkeys = new ArrayList<ForeignKey>(10);
		for(List<ForeignKey> values : fkValues)
		{
			fkeys.addAll(values);
		}
		this.catalog.getSchema().getForeignKeys().clear();
		this.catalog.getSchema().getForeignKeys().addAll(fkeys);
	}

	public void addTable(String schemaName, String catalogName, String tableName) {
		String tblName = tableName; //StringDbsUtils.formatTableName(tableName);
		if(tables == null)
		{
			tables = new HashMap<String, Table>(10);
		}
		if(tables.containsKey(tblName)) {
			
		} else {
			Table table = factory.createTable();
			table.setName(tblName);
			table.setSchema(schemaName);
			table.setCatalog(catalogName);
			tables.put(tblName, table);
			this.catalog.getSchema().getTables().add(table);
		}
	}

	public Table getTable(String fkSchema, String fkCatalog, String fkTableName) {
		//StringDbsUtils.formatTableName(fkTableName);
		return tables.get(fkTableName);
	}

	public Map<String, Table> getTables() {
		return tables;
	}

	public Map<String, List<ForeignKey>> getOneToManyCandidates() {
		return oneToManyCandidates;
	}

	public static Column getColumnByName(Table table, Column column)
	{
		for(Column col : table.getColumns())
		{
			if(col.getName().equals(column.getName()))
			{
				return col;
			}
		}
		return null;
	}
	
	public static String qualify(String catalog2, String schema2, Object name2,
			char c) {
		return catalog2+c+schema2+c+name2;
	}

	public static void addColumn(Table table, Column column2) {
		table.getColumns().add(column2);
		column2.setOwner(table);
	}

	public static void addUniqueKey(Table table, UniqueKey key) {
		table.getUniqueKeys().add(key);		
	}
	
	public static ForeignKey createForeignKey(String fkName, List<Column> columns2,
			String className, List<Column> refColumns, Table table) {
		ForeignKey fkey = factory.createForeignKey();
		fkey.setName(fkName);
		fkey.getColumns().clear();
		fkey.getColumns().addAll(columns2);
		for(Column col : columns2) col.setFK(true);
		fkey.setTable(table);
		fkey.getReferencedColumns().clear();
		fkey.getReferencedColumns().addAll(refColumns);
		for(Column col : refColumns) col.setReferencedFK(true);
		return fkey;
	}
	
	public static void addIndex(Table table, Index index) {
		table.getIndexes().add(index);
	}
	
	public static void addIndexColumn(Key index, Column column) {
		index.getColumns().add(column);		
	}

	public static MetadataFactory getFactory() {
		return factory;
	}

	public Catalog getCatalog() {
		return catalog;
	}

	public void setCatalog(Catalog catalog) {
		this.catalog = catalog;
	}
	
	public static Column getColumn(Table table, String columnName) {
		String colName = columnName; //StringDbsUtils.formatColumnName(columnName);
		Column column = DatabaseCollector.getFactory().createColumn();
		column.setName(colName);
		Column existing = DatabaseCollector.getColumnByName(table, column); 
			//table.getColumnByName(column);
		if (existing != null) {
			column = existing;
		}
		return column;
	}
}
